package main.leetcode.primary.from501to600;

import main.datastruc.TreeNode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 501.二叉搜索树中的众数
 *
 * <p>给定一个有相同值的二叉搜索树（BST），找出 BST 中的所有众数（出现频率最高的元素）。
 *
 * <p>假定 BST 有如下定义：
 *
 * <p>结点左子树中所含结点的值小于等于当前结点的值 结点右子树中所含结点的值大于等于当前结点的值 左子树和右子树都是二叉搜索树
 *
 * <p>提示：如果众数超过1个，不需考虑输出顺序
 *
 * <p>进阶：你可以不使用额外的空间吗？（假设由递归产生的隐式调用栈的开销不被计算在内）
 *
 * <p>来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/find-mode-in-binary-search-tree
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class ex501 {
    private List<Integer> list;
    private int max;
    private int curCnt;
    private int curVal;

    public static void main(String[] args) {
        TreeNode root = TreeNode.creCmpBTree(new int[] {1, 0, 2, 0, 0, 2, 2});
        System.out.println(Arrays.toString(new ex501().findMode(root)));
    }

    public int[] findMode(TreeNode root) {
        if (root == null) {
            return new int[0];
        }
        list = new ArrayList<>();
        inOrder(root);
        int[] res = new int[list.size()];
        for (int i = 0; i < list.size(); ++i) {
            res[i] = list.get(i);
        }
        return res;
    }

    private void inOrder(TreeNode root) {
        if (root == null) {
            return;
        }
        inOrder(root.left);
        if (root.val == curVal) {
            ++curCnt;
        } else {
            curVal = root.val;
            curCnt = 1;
        }
        if (curCnt == max) {
            list.add(curVal);
        } else if (curCnt > max) {
            list.clear();
            list.add(root.val);
            max = curCnt;
        }
        inOrder(root.right);
    }
}
